﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq.Expressions;
using DL.Domain.PublicModels;
using DL.Utils.Extensions;
using DL.Utils.Helper;
using DL.IService;
using DL.Utils.Log.Nlog;

namespace DL.Service
{
	public class BaseService<T> : DbContext, IBaseService<T> where T : class, new()
	{
		#region 添加操作
		/// <summary>
		/// 添加一条数据
		/// </summary>
		/// <param name="parm">T</param>
		/// <returns></returns>
		public async Task<ApiResult<string>> AddAsync(T parm, bool Async = true)
		{
			var res = new ApiResult<string>() { statusCode = (int)ApiEnum.Error };
			try
			{
				var dbres = Async ? await Db.Insertable<T>(parm).ExecuteCommandAsync() : Db.Insertable<T>(parm).ExecuteCommand();
				res.data = dbres.ToString();
				res.statusCode = (int)ApiEnum.Status;
			}
			catch (Exception ex)
			{
				res.msg = ApiEnum.Error.GetEnumText() + ex.Message;
				//LoggerHelper.Default.ProcessError((int)ApiEnum.Error, ex.Message);
			}
			return res;
		}

		/// <summary>
		/// 批量添加数据
		/// </summary>
		/// <param name="parm">List<T></param>
		/// <returns></returns>
		public async Task<ApiResult<string>> AddListAsync(List<T> parm, bool Async = true)
		{
			var res = new ApiResult<string>() { statusCode = (int)ApiEnum.Error };
			try
			{
				var dbres = Async ? await Db.Insertable<T>(parm).ExecuteCommandAsync() : Db.Insertable<T>(parm).ExecuteCommand();
				res.data = dbres.ToString();
				res.statusCode = (int)ApiEnum.Status;
			}
			catch (Exception ex)
			{
				res.msg = ApiEnum.Error.GetEnumText() + ex.Message;
				//LoggerHelper.Default.ProcessError((int)ApiEnum.Error, ex.Message);
			}
			return res;
		}
		#endregion

		#region 查询操作
		/// <summary>
		/// 获得一条数据
		/// </summary>
		/// <param name="where">Expression<Func<T, bool>></param>
		/// <returns></returns>
		public async Task<ApiResult<T>> GetModelAsync(Expression<Func<T, bool>> where, bool Async = true)
		{
            var res = new ApiResult<T>
            {
                statusCode = 200,
                data = Async ? await Db.Queryable<T>().Where(where).FirstAsync() ?? new T() { }
                : Db.Queryable<T>().Where(where).First() ?? new T() { }
			};
			return res;
		}

		/// <summary>
		/// 获得一条数据
		/// </summary>
		/// <param name="parm">string</param>
		/// <returns></returns>
		public async Task<ApiResult<T>> GetModelAsync(string parm, bool Async = true)
		{
			var res = new ApiResult<T>
			{
				statusCode = 200,
				data = Async ? await Db.Queryable<T>().Where(parm).FirstAsync() ?? new T() { }
				: Db.Queryable<T>().Where(parm).First() ?? new T() { }
			};
			return res;
		}

		/// <summary>
		/// 获得列表——分页
		/// </summary>
		/// <param name="parm">PageParm</param>
		/// <returns></returns>
		public async Task<ApiResult<PageReply<T>>> GetPagesAsync(PageParm parm, bool Async = true)
		{
			var res = new ApiResult<PageReply<T>>();
			try
			{
				res.data = Async ? await Db.Queryable<T>()
						.ToPageAsync(parm.page, parm.limit) : Db.Queryable<T>()
						.ToPage(parm.page, parm.limit);
			}
			catch (Exception ex)
			{
				res.msg = ApiEnum.Error.GetEnumText() + ex.Message;
				res.statusCode = (int)ApiEnum.Error;
				//LoggerHelper.Default.ProcessError((int)ApiEnum.Error, ex.Message);
			}
			return res;
		}

		/// <summary>
		/// 分页
		/// </summary>
		/// <param name="parm">分页参数</param>
		/// <param name="where">条件</param>
		/// <param name="order">排序值</param>
		/// <param name="orderEnum">排序方式OrderByType</param>
		/// <returns></returns>
		public async Task<ApiResult<PageReply<T>>> GetPagesAsync(PageParm parm, Expression<Func<T, bool>> where,
			Expression<Func<T, object>> order, DbOrderEnum orderEnum, bool Async = true)
		{
			var res = new ApiResult<PageReply<T>>();
			try
			{
				var query = Db.Queryable<T>()
						.Where(where)
						.OrderByIF((int)orderEnum == 1, order, SqlSugar.OrderByType.Asc)
						.OrderByIF((int)orderEnum == 2, order, SqlSugar.OrderByType.Desc);
				res.data = Async ? await query.ToPageAsync(parm.page, parm.limit) : query.ToPage(parm.page, parm.limit);
			}
			catch (Exception ex)
			{
				res.msg = ApiEnum.Error.GetEnumText() + ex.Message;
				res.statusCode = (int)ApiEnum.Error;
				//LoggerHelper.Default.ProcessError((int)ApiEnum.Error, ex.Message);
			}
			return res;
		}

		/// <summary>
		/// 获得列表
		/// </summary>
		/// <param name="parm">PageParm</param>
		/// <returns></returns>
		public async Task<ApiResult<List<T>>> GetListAsync(Expression<Func<T, bool>> where,
			Expression<Func<T, object>> order, DbOrderEnum orderEnum, bool Async = true)
		{
			var res = new ApiResult<List<T>>();
			try
			{
				var query = Db.Queryable<T>()
                        .WhereIF(where!=null,where)
						//.Where(where)
						.OrderByIF((int)orderEnum == 1, order, SqlSugar.OrderByType.Asc)
						.OrderByIF((int)orderEnum == 2, order, SqlSugar.OrderByType.Desc);
				res.data = Async ? await query.ToListAsync() : query.ToList();
			}
			catch (Exception ex)
			{
				res.msg = ApiEnum.Error.GetEnumText() + ex.Message;
				res.statusCode = (int)ApiEnum.Error;
				//LoggerHelper.Default.ProcessError((int)ApiEnum.Error, ex.Message);
			}
			return res;
		}

		/// <summary>
		/// 获得列表，不需要任何条件
		/// </summary>
		/// <returns></returns>
		public async Task<ApiResult<List<T>>> GetListAsync(bool Async = true)
		{
			var res = new ApiResult<List<T>>();
			try
			{
				res.data = Async ? await Db.Queryable<T>().ToListAsync() : Db.Queryable<T>().ToList();
			}
			catch (Exception ex)
			{
				res.msg = ApiEnum.Error.GetEnumText() + ex.Message;
				res.statusCode = (int)ApiEnum.Error;
				//LoggerHelper.Default.ProcessError((int)ApiEnum.Error, ex.Message);
			}
			return res;
		}
		#endregion

		#region 修改操作
		/// <summary>
		/// 修改一条数据
		/// </summary>
		/// <param name="parm">T</param>
		/// <returns></returns>
		public async Task<ApiResult<string>> UpdateAsync(T parm, bool Async = true)
		{
			var res = new ApiResult<string>() { statusCode = (int)ApiEnum.Error };
			try
			{
				var dbres = Async ? await Db.Updateable<T>(parm).ExecuteCommandAsync() : Db.Updateable<T>(parm).ExecuteCommand();
				res.data = dbres.ToString();
				res.statusCode = (int)ApiEnum.Status;
			}
			catch (Exception ex)
			{
				res.msg = ApiEnum.Error.GetEnumText() + ex.Message;
				//LoggerHelper.Default.ProcessError((int)ApiEnum.Error, ex.Message);
			}
			return res;
		}

		/// <summary>
		/// 批量修改
		/// </summary>
		/// <param name="parm">T</param>
		/// <returns></returns>
		public async Task<ApiResult<string>> UpdateAsync(List<T> parm, bool Async = true)
		{
			var res = new ApiResult<string>() { statusCode = (int)ApiEnum.Error };
			try
			{
				var dbres = Async ? await Db.Updateable<T>(parm).ExecuteCommandAsync() : Db.Updateable<T>(parm).ExecuteCommand();
				res.data = dbres.ToString();
				res.statusCode = (int)ApiEnum.Status;
			}
			catch (Exception ex)
			{
				res.msg = ApiEnum.Error.GetEnumText() + ex.Message;
				//LoggerHelper.Default.ProcessError((int)ApiEnum.Error, ex.Message);
			}
			return res;
		}

		/// <summary>
		/// 修改一条数据，可用作假删除
		/// </summary>
		/// <param name="columns">修改的列=Expression<Func<T,T>></param>
		/// <param name="where">Expression<Func<T,bool>></param>
		/// <returns></returns>
		public async Task<ApiResult<string>> UpdateAsync(Expression<Func<T, T>> columns,
			Expression<Func<T, bool>> where, bool Async = true)
		{
			var res = new ApiResult<string>() { statusCode = (int)ApiEnum.Error };
			try
			{
				var dbres = Async ? await Db.Updateable<T>().UpdateColumns(columns).Where(where).ExecuteCommandAsync()
					: Db.Updateable<T>().UpdateColumns(columns).Where(where).ExecuteCommand();
				res.data = dbres.ToString();
				res.statusCode = (int)ApiEnum.Status;
			}
			catch (Exception ex)
			{
				res.msg = ApiEnum.Error.GetEnumText() + ex.Message;
				//LoggerHelper.Default.ProcessError((int)ApiEnum.Error, ex.Message);
			}
			return res;
		}
		#endregion

		#region 删除操作
		/// <summary>
		/// 删除一条或多条数据
		/// </summary>
		/// <param name="parm">string</param>
		/// <returns></returns>
		public async Task<ApiResult<string>> DeleteAsync(string parm, bool Async = true)
		{
			var res = new ApiResult<string>() { statusCode = (int)ApiEnum.Error };
			try
			{
				var list =  UtilsHelper.StrToListString(parm);
				var dbres = Async ? await Db.Deleteable<T>().In(list.ToArray()).ExecuteCommandAsync() : Db.Deleteable<T>().In(list.ToArray()).ExecuteCommand();
				res.data = dbres.ToString();
				res.statusCode = (int)ApiEnum.Status;
			}
			catch (Exception ex)
			{
				res.msg = ApiEnum.Error.GetEnumText() + ex.Message;
				//LoggerHelper.Default.ProcessError((int)ApiEnum.Error, ex.Message);
			}
			return res;
		}

		/// <summary>
		/// 删除一条或多条数据
		/// </summary>
		/// <param name="where">Expression<Func<T, bool>></param>
		/// <returns></returns>
		public async Task<ApiResult<string>> DeleteAsync(Expression<Func<T, bool>> where, bool Async = true)
		{
			var res = new ApiResult<string>() ;
			try
			{
				var dbres = Async ? await Db.Deleteable<T>().Where(where).ExecuteCommandAsync() : Db.Deleteable<T>().Where(where).ExecuteCommand();
				res.data = dbres.ToString();
				res.statusCode = (int)ApiEnum.Status;
				res.msg = "删除成功";
			}
			catch (Exception ex)
			{
				res.statusCode = (int)ApiEnum.Error;
				res.msg = ApiEnum.Error.GetEnumText() + ex.Message;
				NLogHelper.Error( ex.Message);
			}
			return res;
		}
		#endregion
	}
}
